package com.fingard.dsp.bank.directbank.zyb02;

import java.sql.Connection;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

public class ZYB02Transaction extends ZYB02Base implements ITransaction {
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        String seqNumberStart = getBankConfig().getMapValueByKey("Sys_Head","CONSUMER_ID")+reqHeader.corporation;
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        //写返回ATS的统一头部信息
        retAts.writeStart();
        try {
            ZYB02Header tmpBankHeader = new ZYB02Header();
            //tmpBankHeader.SEQ_NO = reqHeader.transSeqID;
            tmpBankHeader.SEQ_NO = seqNumberStart+reqHeader.transSeqID;
            tmpBankHeader.TRAN_CODE = getBankConfig().getMapValueByKey("TRANS_CODE", "TRANSACTION");
            String transTime = p_req7516.reqHeader.transTime;
            tmpBankHeader.TRAN_DATE = Format.Date8Format.format(DateHelper.convertToDateExtra(transTime));
            tmpBankHeader.TRAN_TIMESTAMP = Format.Time9Format.format(DateHelper.convertToDateExtra(transTime));
            tmpBankHeader.USER_IP = getIpInfoMap(p_req7516.getOriReqXml()).get("userIP");
            tmpBankHeader.SERVER_IP = getIpInfoMap(p_req7516.getOriReqXml()).get("serverIP");

            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int pageNumber = 0;//页码
            int totalPage = 0;
            int totalNumber = 0;//总行数
            int totalNumberCurrent = 0;

            boolean tmpQryNext = true;
            while (tmpQryNext && tmpRespCode.length() == 0) {//分页查询
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                xmlWriter.autoFormat = false;
                //写入通用的头部节点
                writeCommonHeader(xmlWriter, tmpBankHeader);
                /**
                 * 第一页
                 *<CURRENT_NUM>0</CURRENT_NUM>
                 *<PAGE_START>1</PAGE_START>
                 *<PAGE_END>30</PAGE_END>
                 *<TOTAL_NUM>30</TOTAL_NUM>每页30条
                 *第二页
                 *<CURRENT_NUM>30</CURRENT_NUM>
                 *<PAGE_START>31</PAGE_START>
                 *<PAGE_END>60</PAGE_END>
                 *<TOTAL_NUM>30</TOTAL_NUM>每页30条
                 */
                xmlWriter.insertIntoTag("CURRENT_NUM",StringHelper.valueOf(pageNumber));
                xmlWriter.insertIntoTag("PAGE_START",StringHelper.valueOf(pageNumber+1));
                xmlWriter.insertIntoTag("PAGE_END",StringHelper.valueOf(pageNumber+Integer.parseInt(getBankConfig().getMapValueByKey("APP_HEAD", "TOTAL_NUM"))));
                /*xmlWriter.insertIntoTag("CURRENT_NUM",StringHelper.valueOf(pageNumber));
                xmlWriter.insertIntoTag("SEQ_NO",tmpBankHeader.SEQ_NO+pageNumber);*/

                xmlWriter.writeElementString("BASE_ACCT_NO", p_req7516.actNum);
                //调试的时候去掉日期，带上日期银行无返回记录
                String testTransaction = getBankConfig().getValueAsString("testTransaction");
                if(testTransaction == null || StringHelper.isNullOrEmpty(testTransaction)) {
                    xmlWriter.writeElementString("START_DATE", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    xmlWriter.writeElementString("END_DATE", Format.Date8Format.format(tmpCalendarTo.getTime()));
                } else {
                    xmlWriter.writeElementString("START_DATE", getBankConfig().getValueAsString("STARTDATE"));
                    xmlWriter.writeElementString("END_DATE", getBankConfig().getValueAsString("ENDDATE"));
                }
                xmlWriter.writeElementString("CCY", getBankConfig().getMapValueByKey("currencyMapping", p_req7516.actCur));

                xmlWriter.writeEndElement();
                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                XmlTextReader tmpBkReader;
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpStatus = tmpBkReader.getFirstText("/Reply_Msg/Sys_Head/RET_STATUS");
                        String ret_code = tmpBkReader.getFirstText("/Reply_Msg/Sys_Head/RET_ARRAY/Row/RET_CODE");
                        String tmpStatusText = tmpBkReader.getFirstText("/Reply_Msg/Sys_Head/RET_ARRAY/Row/RET_MSG");
                        if ((tmpStatus != null && tmpStatus.equals(TMPSTATUS)) && (ret_code != null && ret_code.equals(RET_CODE))) {
                            //<editor-fold desc="总页数赋值">
                            String totalPageFieldPath = "/Reply_Msg/Body/APP_HEAD/TOTAL_PAGES";
                            if (tmpBkReader.getFirstText(totalPageFieldPath) != null && tmpBkReader.getFirstText(totalPageFieldPath).trim().length() > 0) {
                                if(totalPage == 0) {
                                    totalPage = Integer.parseInt(tmpBkReader.getFirstText(totalPageFieldPath));
                                } else {
                                    if(totalPage != Integer.parseInt(tmpBkReader.getFirstText(totalPageFieldPath))) {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "银行每次返回的总页数不相等！";
                                        break;
                                    }
                                }
                            }
                            //</editor-fold>
                            //<editor-fold desc="总行数赋值">
                            String totalCountFieldPath = "/Reply_Msg/Body/APP_HEAD/TOTAL_ROWS";
                            if (tmpBkReader.getFirstText(totalCountFieldPath) != null && tmpBkReader.getFirstText(totalCountFieldPath).trim().length() > 0) {
                                if(totalNumber == 0) {
                                    totalNumber = Integer.parseInt(tmpBkReader.getFirstText(totalCountFieldPath));
                                } else {
                                    if(totalNumber != Integer.parseInt(tmpBkReader.getFirstText(totalCountFieldPath))) {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "银行每次返回的总记录数不相等！";
                                        break;
                                    }
                                }
                            }
                            //</editor-fold>
                            while (tmpBkReader.read("/Reply_Msg/Body/TRAN_HIST_DETAIL/Row")) {
                                totalNumberCurrent++;
                                RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                //从响应报文取数给tmpReDetail对象赋值
                                tmpRetDetail.recAccBank = tmpBkReader.readedXElement.getSingleText("OTH_BANK_NAME");
                                tmpRetDetail.recAccNum = tmpBkReader.readedXElement.getSingleText("TFR_ACCT_NO");
                                tmpRetDetail.recAccName = tmpBkReader.readedXElement.getSingleText("TFR_ACCT_NAME");
                                tmpRetDetail.cur = tmpBkReader.readedXElement.getSingleText("CCY");
                                String CR_DR_MAINT_IND = tmpBkReader.readedXElement.getSingleText("CR_DR_MAINT_IND");
                                if (StringHelper.hasAnyChar(CR_DR_MAINT_IND)) {
                                    if (CR_DR_MAINT_IND.equals(DEBIT)) {
                                        tmpRetDetail.cdFlag = "1";
                                    }
                                    if (CR_DR_MAINT_IND.equals(CREDIT)) {
                                        tmpRetDetail.cdFlag = "2";
                                    }
                                }
                                tmpRetDetail.tranAmt = tmpBkReader.readedXElement.getSingleText("TRAN_AMT").trim();
                                tmpRetDetail.accBal = tmpBkReader.readedXElement.getSingleText("ACTUAL_BAL_AMT").trim();
                                String tranDate = tmpBkReader.readedXElement.getSingleText("TRAN_DATE");
                                tmpRetDetail.tranDate = Format.Date10Format.format(DateHelper.convertToDateExtra(tranDate));
                                if (StringHelper.hasAnyChar(tmpRetDetail.tranDate)) {
                                    tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " + tmpBkReader.readedXElement.getSingleText("TRAN_TIME");
                                } else {
                                    tmpRetDetail.tranTime = tmpBkReader.readedXElement.getSingleText("TRAN_TIME");
                                }
                                //tmpRetDetail.valueDate = tmpBkReader.readedXElement.getSingleText("EFFECT_DATE");
                                String valueDate = tmpBkReader.readedXElement.getSingleText("EFFECT_DATE");
                                tmpRetDetail.valueDate = Format.Date10Format.format(DateHelper.convertToDateExtra(valueDate));
                                if (StringHelper.isNullOrEmpty(tmpRetDetail.valueDate)) {
                                    tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                }
                                tmpRetDetail.usage = tmpBkReader.readedXElement.getSingleText("NARRATIVE");//用途
                                String channel_seq_no = tmpBkReader.readedXElement.getSingleText("CHANNEL_SEQ_NO");//全局流水号
                                StringBuilder errMsg = new StringBuilder();
                                String atsCheckCode = getAtsCheckCode(channel_seq_no,errMsg);
                                if(StringHelper.isNullOrEmpty(atsCheckCode) || errMsg.length() > 0) {
                                    //没查到不抛异常，如果从别的系统做的交易，然后我们这里查明细的时候根据银行流水号是找不到对账码的
                                    WriteBankLogLn("根据全局流水号"+channel_seq_no+"没有查到对账码:"+errMsg.toString());
                                    //throw new Exception("查询对账码失败："+errMsg.toString());
                                } else {
                                    tmpRetDetail.abstr = atsCheckCode;
                                }
                                tmpRetDetail.comment = tmpBkReader.readedXElement.getSingleText("TRAN_NOTE");//备注
                                tmpRetDetail.payCode = tmpBkReader.readedXElement.getSingleText("TRAN_NOTE");//备注，saas那边取备注取得是payCode
                                tmpRetDetail.actNum = p_req7516.actNum;

                                retAts.writeRetDetail(tmpRetDetail);
                            }
                            if(totalNumberCurrent < totalNumber) {
                                pageNumber = pageNumber+Integer.parseInt(getBankConfig().getMapValueByKey("APP_HEAD", "TOTAL_NUM"));
                            } else {
                                tmpQryNext = false;
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpStatusText;
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                    break;
                }
            }

            if(totalNumber != totalNumberCurrent) {
                throw new Exception("循环读取的总记录数和银行返回的总记录数不一致！");
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    //当日明细查询调用历史明细查询方法
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.getXmlReader(),p_req7515.reqHeader);
        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;
        String tmpStrToday = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;
        return d_7516_HisTrans(tmpReq7516);
    }

    /**
     * 根据银行全局流水号查找对账码
     * @param bankSeqID
     * @return
     */
    private String getAtsCheckCode(String bankSeqID,StringBuilder errMsg) {
        if (FGBiz.dspCenter.dspSet.dbConnectionSet != null) {
            try {
                Connection dbConn = null;
                try {
                    dbConn = getDbConnection();
                    Map<String, Object> reqSeqIDMap = JDBCHelper.execQuerySingle(dbConn, "select t.KEYVALUE CHECKCODE from UNIQUEID t left join REQSEQIDMAPPING rm on t.KEYNAME = rm.REQSEQID where rm.BANKREQSEQID = ?", new Object[]{bankSeqID});
                    if (reqSeqIDMap != null && reqSeqIDMap.size() > 0) {
                        return String.valueOf(reqSeqIDMap.get("CHECKCODE"));
                    }
                    errMsg.append("查询为空");
                } catch (Exception ex) {
                    errMsg.append(LogHelper.getStackTrace(ex));
                    ex.printStackTrace();
                } finally {
                    if (dbConn != null) {
                        dbConn.close();
                    }
                }
            } catch (Exception ex) {
                errMsg.append(LogHelper.getStackTrace(ex));
                ex.printStackTrace();
            }
        } else {
            errMsg.append("数据库连接未配置或有误");
        }
        return "";
    }
}
